package com.freecloud.javabasics.network.rpc.server.provider;

import com.freecloud.javabasics.network.rpc.server.api.RpcRequest;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Map;

/**
 * @Author: maomao
 * @Date: 2020-03-15 21:17
 */
public class ProcessorHandler implements Runnable {

    private Socket socket;
    private Object service;
    private Map<String,Object> handlerMap;


//    public ProcessorHandler( Object service,Socket socket) {
//        this.socket = socket;
//        this.service = service;
//    }

    public ProcessorHandler( Socket socket,Map<String,Object> handlerMap) {
        this.socket = socket;
        this.handlerMap = handlerMap;
    }



    @Override
    public void run() {
        ObjectInputStream objectInputStream = null;
        ObjectOutputStream objectOutputStream = null;

        try {
            objectInputStream = new ObjectInputStream(socket.getInputStream());

            //请求哪个类，方法名称，参数
            RpcRequest rpcRequest = (RpcRequest)objectInputStream.readObject();

            Object result = invoke(rpcRequest);

            objectOutputStream = new ObjectOutputStream(socket.getOutputStream()) ;

            objectOutputStream.writeObject(result);
            objectOutputStream.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }finally {
            if(objectInputStream != null){
                try {
                    objectInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(objectOutputStream != null){
                try {
                    objectOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

//    private Object invoke(RpcRequest request) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//        //拿到客户端请求的参数
//        Object[] args = request.getParameters();
//        //获得每个参数的类型
//        Class<?>[] types = new Class[args.length];
//        for (int i = 0; i < args.length; i++) {
//            types[i] = args[i].getClass();
//        }
//        //
//        Class clazz = Class.forName(request.getClassName());
//        Method method = clazz.getMethod(request.getMethodName(),types);
//        Object result = method.invoke(service,request.getParameters());
//        return result;
//    }

    private Object invoke(RpcRequest request) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        Object service = handlerMap.get(request.getClassName());
        if(service == null){
            throw  new RuntimeException("service not find : " + request.getClassName());
        }

        //拿到客户端请求的参数
        Object[] args = request.getParameters();
        //获得每个参数的类型
        Class<?>[] types = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
            types[i] = args[i].getClass();
        }
        //
        Class clazz = Class.forName(request.getClassName());
        Method method = clazz.getMethod(request.getMethodName(),types);
        Object result = method.invoke(service,request.getParameters());
        return result;
    }
}
